﻿Imports RegExUtility.ViewModel
Imports System.ComponentModel

Public Class ViewNavigator
    Implements IViewNavigator

#Region "Events"
    Friend Event LongProcessStarted As EventHandler
    Friend Event LongProcessCompleted As EventHandler
    Friend Event LongProcessProgressUpdated(sender As Object, progressPercentage As Integer, userState As Object)
#End Region

#Region "Properties"
#Region "Constants"
    ' Insert Constant Declarations Here
#End Region

    Public Shared ReadOnly Property Instance As ViewNavigator
        Get
            Static l_instance As New ViewNavigator()
            Return l_instance
        End Get
    End Property

    Public ReadOnly Property CommandFactory As ViewModel.ICommandFactory Implements IViewNavigator.CommandFactory
        Get
            Return ViewCommandFactory.Instance
        End Get
    End Property

    Private _longProcessRunning As Boolean
    Public Property LongProcessRunning() As Boolean
        Get
            Return _longProcessRunning
        End Get
        Private Set(ByVal value As Boolean)
            If _longProcessRunning <> value Then
                _longProcessRunning = value
                If value Then
                    OnLongProcessStarted()
                Else
                    OnLongProcessCompleted()
                End If
            End If
        End Set
    End Property

#End Region

#Region "Constructors"
    Private Sub New()
    End Sub
#End Region

#Region "Methods"
    Public Sub DisplayErrorMessage(title As String, message As String, critical As Boolean) Implements IViewNavigator.DisplayErrorMessage
        MessageBox.Show(message, title, MessageBoxButton.OK, If(critical, MessageBoxImage.Error, MessageBoxImage.Warning))
    End Sub

    Public Function GetFileHandle() As System.IO.FileInfo Implements IViewNavigator.GetFileHandle
        Dim l_dialog As New Microsoft.Win32.OpenFileDialog()
        If l_dialog.ShowDialog() Then
            Return New IO.FileInfo(l_dialog.FileName)
        Else
            Return Nothing
        End If
    End Function

    Public Function GetDirectoryHandle() As System.IO.DirectoryInfo Implements IViewNavigator.GetDirectoryHandle
        Dim l_dialog As New System.Windows.Forms.FolderBrowserDialog
        l_dialog.Description = "Select a Root Directory to Begin Searching"
        l_dialog.ShowNewFolderButton = False
        If l_dialog.ShowDialog() = Forms.DialogResult.OK Then
            Return New IO.DirectoryInfo(l_dialog.SelectedPath)
        Else
            Return Nothing
        End If
    End Function

    Public Function GoToLiteralTextInput(Optional literalText As String = Nothing) As LiteralTextInputViewModel Implements IViewNavigator.GoToLiteralTextInput
        With DirectCast(Application.Current.MainWindow, MainWindow).ViewModel
            If Not literalText Is Nothing Then .LiteralTextInput.InputText = literalText
            .SelectedInputViewModel = .LiteralTextInput
            Return .LiteralTextInput
        End With
    End Function

    Public Sub ExecuteLongProcess(process As Func(Of Object, Action(Of Integer, Object), Object), callback As RunWorkerCompletedEventHandler) Implements ViewModel.IViewNavigator.ExecuteLongProcess
        If Not Me.LongProcessRunning Then
            Me.LongProcessRunning = True

            Dim l_worker As New BackgroundWorker()

            AddHandler l_worker.DoWork,
                Sub(sender As Object, e As DoWorkEventArgs)
                    Dim l_caller = DirectCast(sender, BackgroundWorker)
                    e.Result = process(e.Argument, AddressOf l_caller.ReportProgress)
                End Sub

            AddHandler l_worker.ProgressChanged,
                Sub(sender As Object, e As ProgressChangedEventArgs)
                    OnLongProcessProgressUpdated(e.ProgressPercentage, e.UserState)
                End Sub

            AddHandler l_worker.RunWorkerCompleted,
                Sub(sender As Object, e As RunWorkerCompletedEventArgs)
                    Me.LongProcessRunning = False
                End Sub

            l_worker.RunWorkerAsync()
        End If
    End Sub

#Region "Event Raiser Methods"

    Private Sub OnLongProcessStarted()
        RaiseEvent LongProcessStarted(sender:=Me, e:=Nothing)
    End Sub

    Private Sub OnLongProcessCompleted()
        RaiseEvent LongProcessCompleted(sender:=Me, e:=Nothing)
    End Sub

    Private Sub OnLongProcessProgressUpdated(progressPercentage As Integer, userState As Object)
        RaiseEvent LongProcessProgressUpdated(sender:=Me, progressPercentage:=progressPercentage, userState:=userState)
    End Sub

#End Region

#Region "Event Handlers"

#End Region
#End Region








    Public Class ViewCommandFactory
        Implements ICommandFactory

#Region "Events"
        ' Insert Event Declarations Here
#End Region

#Region "Properties"
#Region "Constants"
        ' Insert Constant Declarations Here
#End Region

        Public Shared ReadOnly Property Instance As ViewCommandFactory
            Get
                Static l_instance As New ViewCommandFactory()
                Return l_instance
            End Get
        End Property
#End Region

#Region "Constructors"
        Private Sub New()
        End Sub
#End Region

#Region "Methods"
        Public Function CreateCommand(ByVal executeCallback As Action(Of Object), ByVal executable As Boolean) As IViewModelCommand Implements ICommandFactory.CreateCommand
            Return New ViewCommand(executeCallback, executable)
        End Function

#Region "Event Raiser Methods"
        ' Insert Method Declarations which Raise an Event Here
#End Region

#Region "Event Handlers"
        ' Insert Method Declarations which Handle an Event Here
#End Region
#End Region









        Private Class ViewCommand
            Implements ICommand
            Implements IViewModelCommand

#Region "Events"
            Public Event CanExecuteChanged(ByVal sender As Object, ByVal e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged
#End Region

#Region "Properties"
#Region "Constants"
            ' Insert Constant Declarations Here
#End Region

            Private _executeCallbackReference As Action(Of Object)
            Private Property ExecuteCallback As Action(Of Object)
                Get
                    Return _executeCallbackReference
                End Get
                Set(ByVal value As Action(Of Object))
                    _executeCallbackReference = value
                End Set
            End Property

            Private _executable As Boolean
            Public Property Executable As Boolean Implements IViewModelCommand.Executable
                Get
                    Return _executable
                End Get
                Set(ByVal value As Boolean)
                    If _executable <> value Then
                        _executable = value
                        RaiseEvent CanExecuteChanged(sender:=Me, e:=EventArgs.Empty)
                    End If
                End Set
            End Property
#End Region

#Region "Constructors"
            Public Sub New(ByVal executeCallback As Action(Of Object), ByVal executable As Boolean)
                Me.ExecuteCallback = executeCallback
                Me.Executable = executable
            End Sub
#End Region

#Region "Methods"
            Public Function CanExecute(ByVal parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
                Return Me.Executable
            End Function

            Public Sub Execute(ByVal parameter As Object) Implements System.Windows.Input.ICommand.Execute, IViewModelCommand.Execute
                ExecuteCallback.Invoke(parameter)
            End Sub

#Region "Event Raiser Methods"
            ' Insert Method Declarations which Raise an Event Here
#End Region

#Region "Event Handlers"
            ' Insert Method Declarations which Handle an Event Here
#End Region
#End Region

        End Class

    End Class

End Class
